package com.heima.wemedia.scan.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.map.MapUtil;
import com.alibaba.fastjson.JSON;
import com.heima.aliyun.AliyunGreenTemplate;
import com.heima.article.client.ArticleFeignClient;
import com.heima.file.MinIOTemplate;
import com.heima.model.article.dao.ArticleDto;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.wemedia.entity.WmChannel;
import com.heima.model.wemedia.entity.WmNews;
import com.heima.model.wemedia.entity.WmUser;
import com.heima.utils.common.SensitiveWordUtil;
import com.heima.wemedia.scan.dao.WmChannelDao;
import com.heima.wemedia.scan.dao.WmNewsDao;
import com.heima.wemedia.scan.dao.WmUserDao;
import com.heima.wemedia.scan.service.WmNewsAutoScanService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class WmNewsAutoScanServiceImpl implements WmNewsAutoScanService {

    @Resource
    private WmNewsDao wmNewsDao;

    @Resource
    private AliyunGreenTemplate aliyunGreenTemplate;

    @Resource
    private MinIOTemplate minIOTemplate;

    @Resource
    private WmUserDao wmUserDao;

    @Resource
    private WmChannelDao wmChannelDao;

    @Resource
    private ArticleFeignClient articleFeignClient;

    @Override
    public void autoScanNews(Long newsId) {

        //1.校验参数
        WmNews wmNews = wmNewsDao.queryById(newsId);
        if (wmNews == null) {
           throw new RuntimeException("文章不存在");
        }

        if (wmNews.getStatus() != 1) {
            return;
        }
        //2. 抽取文章文本内容和图片数据
        Map<String, Object> textAndImages = extractTextAndImages(wmNews);

        String text = (String) textAndImages.get("text");
        boolean sensitiveScan = handleSensitiveScan(wmNews, text);
        if (!sensitiveScan) {
            return;
        }

//        boolean textScan = handleTextScan(wmNews, text);
//        if (!textScan) {
//            return;
//        }

//        List<String> images = (List<String>) textAndImages.get("images");
//        boolean imagesScan = handleImagesScan(wmNews, images);
//        if (!imagesScan) {
//            return;
//        }

        if (wmNews.getPublishTime().getTime() > System.currentTimeMillis()) {
            updateStatus(wmNews, (short) 8, "审核通过");
        }else {
            saveArticle(wmNews);
        }
    }

    /**
     *   审核通过发布文章
     */
    public void saveArticle(WmNews wmNews) {
       //1. 封装参数
        ArticleDto articleDto = new ArticleDto();
        BeanUtils.copyProperties(wmNews, articleDto);

        //处理数据  id  authorId authorName  channelName  layout
        articleDto.setNewsId(wmNews.getId());
        articleDto.setAuthorId(wmNews.getUserId());

        WmUser wmUser = wmUserDao.queryById(wmNews.getUserId());
        if (wmUser != null) {
            articleDto.setAuthorName(wmUser.getNickname());
        }

        articleDto.setChannelId(wmNews.getChannelId());
        WmChannel wmChannel = wmChannelDao.queryById(wmNews.getChannelId());
        if (wmChannel != null) {
            articleDto.setChannelName(wmChannel.getName());
        }

        if(wmNews.getType() != null){
            articleDto.setLayout(wmNews.getType());
        }

        articleDto.setLayout(wmNews.getType());
        articleDto.setCreatedTime(new Date());
        articleDto.setUpdatedTime(new Date());

        ResponseResult result = articleFeignClient.save(articleDto);
        if(result.getCode()==200){
            updateStatus(wmNews,9,"文章已发布");
        }
    }

    private boolean handleSensitiveScan(WmNews wmNews, String text) {
        if(StringUtils.isEmpty(text)){
            return true;
        }
        Map<String, Integer> map = SensitiveWordUtil.matchWords(text);
        if(MapUtil.isEmpty(map)){
            return true;
        }else {
            updateStatus(wmNews,3,"文章内容保护敏感词:"+map);
            return false;
        }
    }

    // TODO: 2022/4/15

    /**
     *审核图片
     */
    private boolean handleImagesScan(WmNews wmNews, List<String> images) {
        if(CollectionUtil.isEmpty(images)){
            return true;
        }

        images = images.stream().distinct().collect(Collectors.toList());
        List<byte[]> collect = images.stream().map(url -> minIOTemplate.downLoadFile(url)).collect(Collectors.toList());
        Map<String, String> imageScan = aliyunGreenTemplate.greenImageScan(collect);

        if("pass".equals(imageScan.get("suggestion"))){
            updateStatus(wmNews, 8, "审核通过");
        }
        if ("review".equals(imageScan.get("suggestion"))) {
            updateStatus(wmNews,3,"图片含有不确定因素,请等待进一步审核");
        }
        if("block".equals(imageScan.get("suggestion"))){
            updateStatus(wmNews,2,"图片内容涉嫌违规内容,请修改后重新发布");
        }
        return false;
    }

    /**
     *审核文章
     */
    private boolean handleTextScan(WmNews wmNews, String text) {
        if(StringUtils.isEmpty(text)){
            return true;
        }
        Map<String, String> textMap = aliyunGreenTemplate.greenTextScan(text);
        if("pass".equals(textMap.get("suggestion"))){
            updateStatus(wmNews, 8, "审核通过");
        }
        if ("review".equals(textMap.get("suggestion"))) {
            updateStatus(wmNews,3,"文章含有不确定因素,请等待进一步审核");
        }
        if("block".equals(textMap.get("suggestion"))){
            updateStatus(wmNews,2,"文章内容涉嫌违规内容,请修改后重新发布");
        }
        return false;
    }

    /**
     * 修改状态
     */
    private void updateStatus(WmNews wmNews, int status, String reason) {
        wmNews.setStatus(status);
        wmNews.setReason(reason);
        wmNewsDao.update(wmNews);
    }

    /**
     * 封装图片,文章参数
     */
    private Map<String, Object> extractTextAndImages(WmNews wmNews) {
        String content = wmNews.getContent();
        List<Map> list = JSON.parseArray(content, Map.class);

        StringBuilder text = new StringBuilder();
        text.append(wmNews.getTitle());
        List<String> images = new ArrayList<>();

        if(StringUtils.isNotBlank(wmNews.getImages())){
            String[] split = wmNews.getImages().split(",");
            images.addAll(Arrays.asList(split));
        }

        for (Map map : list) {

            if("text".equals(map.get("type"))){
                text.append(map.get("value")).append(",");
            }
            if ("image".equals(map.get("type"))) {
                images.add((String) map.get("value"));
            }
        }


        Map<String, Object> result = new HashMap<>();
        result.put("text", text.toString());
        result.put("images", images);

        return result;

    }
}
